/*  
Janiak A, Kozan E, Lichtenstein M, Oguz C. 
Metaheuristic approaches to the hybrid flow shop scheduling problem
with a cost-related criterion[J].
International Journal of Production Economics 2007;105(2):407-24.

  Algorithm H

*/

#include "data.h"
#include "Activity.h"
#include "global.h"

int ts(data md, schedule &ms, int alpha, int lb, int &maxWait,
	   int &makespan) {

	// Definition:
	int i, j ,  tmpmakespan, iter, maxiter ;
	deque <int> siter,  maxl, av;
	deque <Activity> acts;	

	// Initialization:
	for ( i = 0; i < ms.getnbSched(); i ++ ) {		
		for ( j = 0; j < ms.getnbStages(); j ++ ) {
			Activity act(ms, i, j);
			acts.push_back(act);			
		}		
	}
	
	for ( i = 0; 
	i < ms.getnbMachinesPerStage() * ms.getnbStages();
	i ++)
		 av.push_back(0);

	for ( i = 0; i < ms.getnbSched(); i ++) {
		siter.push_back(ms.getSched(i));
	}

	schedule ms2(md);
	for (i = 0; i < md.getnbJobs(); i ++ ) {
		for( j = 0; j < md.getnbStages() ; j++) {
			ms2.setPtimes(i, j, md.getPtimes(i,j));
		}
	}

	int tabu_size = ms.getnbSched() >= ms.getnbStages()?
		ms.getnbSched(): ms.getnbStages();
	

	for ( i = 0; i < tabu_size ; i ++){
		for ( j = 0; j < ms.getnbSched(); j ++) {
			maxl.push_back( 0 );
		}
	}



	// Starting TS:
	makespan = backtrack( ms, acts, 0, av, 0, 0, 0, alpha, maxWait);


	/*
	cout << "neh: " << makespan << " " << maxWait << endl;


	FILE *istream;
	if(( istream  = fopen( "neh.txt", "w" )) == NULL ) {
		cout<<  "The file was not opened" << endl;
		exit(1);
	}

	for ( int u = 0; u < ms.getnbSched(); u ++) {
		int i = ms.getSched(u);
		for ( int j = 0; j < ms.getnbStages(); j ++ ) {
			fprintf(istream, "%d%s %d%s %d%s %d%s %d%s %d\n", 
				i,",",
				j,",",
				acts[i*ms.getnbStages() + j].getMachine( i, j) , ",",
				acts[i*ms.getnbStages() + j].getStime( i, j), ",", 
				acts[i*ms.getnbStages() + j].getPtime( i, j),  ",",
				acts[i*ms.getnbStages() + j].getEtime( i, j) );
		}
		fprintf(istream, "\n");
	}
	fprintf(istream, "\n");
	fprintf(istream, "%d \n", lb);
	fclose(istream);
	*/

	int k = 0;
	maxiter		=  1000 ;
	
	for( iter = 0; iter < maxiter; iter++) {
				
		non_tabu_move( tabu_size, ms2.getnbSched(), siter, maxl);

		for ( i = 0; i < ms2.getnbSched(); i ++) 
			ms2.setSched( i, siter[i]);

		tmpmakespan = 
			backtrack( ms2, acts, 0, av, 0, 0, 0, alpha, maxWait);
	
		if ( makespan > tmpmakespan) {

			for ( i = 0; i < ms2.getnbSched(); i ++) {
				ms.setSched( i, ms2.getSched(i));
			}
			makespan = tmpmakespan;
			k++;
			cout <<iter << " " <<  k << endl;
		}

		makespan = backtrack( ms, acts, 0, av, 0, 0, 0, alpha, maxWait);	
	

		if ( k == 10) 
			return 0;


	//	cout << iter << " " << makespan  << " " << tmpmakespan<< endl;
		//if((double)((ms.getMakespan() - lb(md)))/lb(md) <0.05 ){

	}
	

	/*	
	cout << "ts: " << makespan << " " << maxWait << endl;
	
	// Gantt chart	
	// FILE *istream;
	if(( istream  = fopen( "ts.txt", "w" )) == NULL ) {
		cout<<  "The file was not opened" << endl;
		exit(1);
	}

	for ( u = 0; u < ms.getnbSched(); u ++) {
		int i = ms.getSched(u);
		for ( int j = 0; j < ms.getnbStages(); j ++ ) {
			fprintf(istream, "%d%s %d%s %d%s %d%s %d%s %d\n", 
				i,",",
				j,",",
				acts[i*ms.getnbStages() + j].getMachine( i, j) , ",",
				acts[i*ms.getnbStages() + j].getStime( i, j), ",", 
				acts[i*ms.getnbStages() + j].getPtime( i, j),  ",",
				acts[i*ms.getnbStages() + j].getEtime( i, j) );
		}
		fprintf(istream, "\n");
	}
	fprintf(istream, "\n");
	fprintf(istream, "%d \n", lb);
	fclose(istream);
	*/


	return 0;
}

